#include "stdafx.h"
#include "wf_dialogfactory.h"

#include <qmessagebox.h>
#include <q3filedialog.h>
//Added by qt3to4:
#include <Q3StrList>
#include <QImageReader>

#include "pf_patternlist.h"
#include "pf_settings.h"
#include "pf_system.h"
#include "pf_actioninterface.h"
#include "pf_document.h"

#include "wf_dimlinear.h"

#include "ui_arcoptions.h"
#include "ui_arctangentialoptions.h"
#include "ui_beveloptions.h"
#include "ui_blockdialog.h"
#include "ui_cadtoolbar.h"
#include "ui_circleoptions.h"
#include "ui_commandwidget.h"
#include "ui_coordinatewidget.h"
#include "ui_dimlinearoptions.h"
#include "ui_dimoptions.h"
#include "ui_dlgarc.h"
#include "ui_dlgattributes.h"
#include "ui_dlgcircle.h"
#include "ui_dlgdimension.h"
#include "ui_dlgdimlinear.h"
#include "ui_dlgellipse.h"
#include "ui_dlghatch.h"
#include "ui_dlginsert.h"
#include "ui_dlgline.h"
#include "ui_dlgmirror.h"
#include "ui_dlgmove.h"
#include "ui_dlgmoverotate.h"
#include "ui_dlgoptionsdrawing.h"
#include "ui_dlgoptionsgeneral.h"
#include "ui_dlgpoint.h"
#include "ui_dlgrotate.h"
#include "ui_dlgrotate2.h"
#include "ui_dlgscale.h"
#include "ui_dlgspline.h"
#include "ui_dlgtext.h"
#include "ui_imageoptions.h"
#include "ui_insertoptions.h"
#include "ui_layerdialog.h"
#include "ui_libraryinsertoptions.h"
#include "ui_lineangleoptions.h"
#include "ui_linebisectoroptions.h"
#include "ui_lineoptions.h"
#include "ui_lineparalleloptions.h"
#include "ui_lineparallelthroughoptions.h"
#include "ui_linepolygon2options.h"
#include "ui_linepolygonoptions.h"
#include "ui_linerelangleoptions.h"
#include "ui_mousewidget.h"
#include "ui_moverotateoptions.h"
#include "ui_printpreviewoptions.h"
#include "ui_roundoptions.h"
#include "ui_selectionwidget.h"
#include "ui_snapdistoptions.h"
#include "ui_splineoptions.h"
#include "ui_textoptions.h"
#include "ui_trimamountoptions.h"

#include "ui_polylineoptions.h"


#include "ui_layerwidget.h"
#include "wf_mainwindowinterface.h"

//QG_DialogFactory* QG_DialogFactory::uniqueInstance = NULL;


/**
 * Constructor.
 *
 * @param parent Pointer to parent widget which can host dialogs.
 * @param ow Pointer to widget that can host option widgets.
 */
WF_DialogFactory::WF_DialogFactory(QWidget* parent, QToolBar* ow)
        : PF_DialogFactoryInterface() {
	PF_DEBUG->print("QG_DialogFactory::QG_DialogFactory");

    this->parent = parent;
    setOptionWidget(ow);

    coordinateWidget = NULL;
    mouseWidget = NULL;
    selectionWidget = NULL;
    cadToolBar = NULL;
    commandWidget = NULL;
    mainWindow = NULL;
	PF_DEBUG->print("QG_DialogFactory::QG_DialogFactory: OK");
}



/**
 * Destructor
 */
WF_DialogFactory::~WF_DialogFactory() {
    PF_DEBUG->print("QG_DialogFactory::~QG_DialogFactory");
    PF_DEBUG->print("QG_DialogFactory::~QG_DialogFactory: OK");
}




/**
 * Shows a message dialog.
 */
void WF_DialogFactory::requestWarningDialog(const PF_String& warning) {
    QMessageBox::information(parent, QMessageBox::tr("Warning"),
                             warning,
                             QMessageBox::Ok);
}



/**
 * Requests a new document from the main window.
 */
PF_GraphicView* WF_DialogFactory::requestNewDocument(const PF_String& fileName, PF_Document* doc) {
	if (mainWindow!=NULL) {
		mainWindow->createNewDocument(fileName, doc);
		return mainWindow->getGraphicView();
	}
	return NULL;
}


/**
 * Shows a dialog for adding a layer. Doesn't add the layer.
 * This is up to the caller.
 *
 * @return a pointer to the newly created layer that
 * should be added.
 */
PF_Layer* WF_DialogFactory::requestNewLayerDialog(PF_LayerList* layerList) {

    PF_Layer* layer = NULL;

    QString layer_name = "noname";
    int i = 2;

    if (layerList!=NULL) {
        while (layerList->find(layer_name) > 0)
            layer_name.sprintf("noname%d", i++);
    }

    // Layer for parameter livery
    layer = new PF_Layer(layer_name);

    UI_LayerDialog dlg(parent, "Layer Dialog");
    dlg.setLayer(layer);
    dlg.setLayerList(layerList);
    if (dlg.exec()) {
        dlg.updateLayer();
    } else {
        delete layer;
        layer = NULL;
    }
    return layer;
}



/**
 * Shows a dialog that asks the user if the selected layer
 * can be removed. Doesn't remove the layer. This is up to the caller.
 *
 * @return a pointer to the layer that should be removed.
 */
PF_Layer* WF_DialogFactory::requestLayerRemovalDialog(PF_LayerList* layerList) {

    PF_Layer* layer = NULL;
    if (layerList==NULL) {
        PF_DEBUG->print(PF_Debug::D_WARNING,
        	"QG_DialogFactory::requestLayerRemovalDialog(): "
        	"layerList is NULL");
        return NULL;
    }
    /*
       if (layerList==NULL) {
           if (container!=NULL && container->rtti()==LX_Define::EntityGraphic) {
               layerList = (PF_LayerList*)container;
           } else {
               return NULL;
           }
       }*/

    // Layer for parameter livery
    layer = layerList->getActive();

    if (layer!=NULL) {
        if (layer->getName()!="0") {
            QMessageBox msgBox(
                    QMessageBox::Warning,
                    QMessageBox::tr("Remove Layer"),
                    QMessageBox::tr("Layer \"%1\" and all "
                                    "entities on it will be removed.")
                    .arg(layer->getName()),
                    QMessageBox::Ok | QMessageBox::Cancel);
            if (msgBox.exec()==QMessageBox::Ok) {}
            else {
                layer = NULL;
            }
        } else {
            QMessageBox::information(parent,
                                     QMessageBox::tr("Remove Layer"),
                                     QMessageBox::tr("Layer \"%1\" can never "
                                                     "be removed.")
                                     .arg(layer->getName()),
                                     QMessageBox::Ok);
        }
    }

    return layer;
}



/**
 * Shows a dialog for editing a layer. A new layer is created and
 * returned. Modifying the layer is up to the caller.
 *
 * @return A pointer to a new layer with the changed attributes
 *         or NULL if the dialog was cancelled.
 */
PF_Layer* WF_DialogFactory::requestEditLayerDialog(PF_LayerList* layerList) {

    PF_DEBUG->print("QG_DialogFactory::requestEditLayerDialog");

    PF_Layer* layer = NULL;
    /*
       if (layerList==NULL) {
           if (container!=NULL && container->rtti()==LX_Define::EntityGraphic) {
               layerList = (PF_LayerList*)container;
           } else {
               return NULL;
           }
       }
    */

    if (layerList==NULL) {
        PF_DEBUG->print(PF_Debug::D_WARNING,
        	"QG_DialogFactory::requestEditLayerDialog(): "
        	"layerList is NULL");
        return NULL;
    }

    // Layer for parameter livery
    if (layerList->getActive()!=NULL) {
        layer = new PF_Layer(*layerList->getActive());

        UI_LayerDialog dlg(parent, QMessageBox::tr("Layer Dialog"));
        dlg.setLayer(layer);
        dlg.setLayerList(layerList);
        dlg.setEditLayer(TRUE);
        if (dlg.exec()) {
            dlg.updateLayer();
        } else {
            delete layer;
            layer = NULL;
        }
    }

    return layer;
}



/**
 * Shows a dialog for adding a block. Doesn't add the block.
 * This is up to the caller.
 *
 * @return a pointer to the newly created block that 
 * should be added.
 */
PF_BlockAttribute WF_DialogFactory::requestNewBlockDialog(PF_BlockList* blockList) {
    //PF_Block* block = NULL;
    PF_BlockAttribute ret;
    ret = PF_BlockAttribute("", PF_Vector(false), false);

    if (blockList==NULL) {
        PF_DEBUG->print(PF_Debug::D_WARNING,
        	"QG_DialogFactory::requestNewBlockDialog(): "
        	"blockList is NULL");
        return ret;
    }

    // Block for parameter livery
    //block = new PF_Block(container, "noname", PF_Vector(0.0,0.0));

    UI_BlockDialog dlg(parent);
    dlg.setBlockList(blockList);
    if (dlg.exec()) {
        ret = dlg.getBlockData();
    }

    return ret;
}



/**
 * Shows a dialog for renaming the currently active block. 
 *
 * @return a pointer to the modified block or NULL on cancellation.
 */
PF_BlockAttribute WF_DialogFactory::requestBlockAttributesDialog(PF_BlockList* blockList) {
    //PF_Block* block = NULL;
    PF_BlockAttribute ret;
    ret = PF_BlockAttribute("", PF_Vector(false), false);

    if (blockList==NULL) {
        PF_DEBUG->print(PF_Debug::D_WARNING,
        	"QG_DialogFactory::requestBlockAttributesDialog(): "
        	"blockList is NULL");
        return ret;
    }
    /*
       if (blockList==NULL) {
           if (container!=NULL && container->rtti()==LX_Define::EntityGraphic) {
               blockList = (PF_BlockList*)container;
           } else {
               return NULL;
           }
       }*/

    // Block for parameter livery
    //block = blockList->getActive();

    UI_BlockDialog dlg(parent, "Rename Block");
    dlg.setBlockList(blockList);
    if (dlg.exec()) {
        //dlg.updateBlock();
        //block->setData();
        ret = dlg.getBlockData();
    }
    //else {
    //	ret = PF_BlockAttribute("", PF_Vector(false));
    //}

    return ret;
}


/**
 * Shows a dialog that asks the user if the selected block
 * can be removed. Doesn't remove the block. This is up to the caller.
 *
 * @return a pointer to the block that should be removed.
 */
PF_Block* WF_DialogFactory::requestBlockRemovalDialog(PF_BlockList* blockList) {
    PF_Block* block = NULL;

    if (blockList==NULL) {
        PF_DEBUG->print(PF_Debug::D_WARNING,
        	"QG_DialogFactory::requestBlockRemovalDialog(): "
        	"blockList is NULL");
        return NULL;
    }

    // Block for parameter livery
    block = blockList->getActive();

    if (block!=NULL) {
        int remove =
            QMessageBox::warning(parent,
                                     QMessageBox::tr("Remove Block"),
                                     QMessageBox::tr("Block \"%1\" and all "
                                                     "its entities will be removed.")
                                     .arg(block->getName()),
                                     QMessageBox::Ok,
                                     QMessageBox::Cancel);
        if (remove==QMessageBox::Ok) {}
        else {
            block = NULL;
        }
    }

    return block;
}

/**
 * Shows a dialog for choosing a file name. Opening the file is up to
 * the caller.
 *
 * @return File name with path and extension to determine the file type
 *         or an empty string if the dialog was cancelled.
 */
PF_String WF_DialogFactory::requestImageOpenDialog() {
    PF_String fn = "";

    // read default settings:
    PF_SETTINGS->beginGroup("/Paths");
    PF_String defDir = PF_SETTINGS->readEntry("/OpenImage",
                       PF_SYSTEM->getHomeDir());
    PF_String defFilter = PF_SETTINGS->readEntry("/ImageFilter",
                          "Portable Network Graphic (*.png)");
    PF_SETTINGS->endGroup();

    bool cancel = false;

    Q3FileDialog fileDlg(NULL, "", true);

    //  
    //Q3StrList f = QImageReader::supportedImageFormats();
    //QStringList formats = QStringList::fromStrList(f);
    QStringList filters;
    QString all = "";
    //filters = QStringList::fromStrList(formats);

    foreach (QByteArray format, QImageReader::supportedImageFormats()) {
		filters.append(format);
		/*  
		 QString ext = (*it);
        QString st;
        if (ext=="JPEG") {
            st = QString("%1 (*.%2 *.jpg)").arg(extToFormat(*it))
                 .arg(QString(*it).lower());
        } else {
            st = QString("%1 (*.%2)").arg(extToFormat(*it))
                 .arg(QString(*it).lower());
        }
        filters.append(st);

        if (!all.isEmpty()) {
            all += " ";
        }

        if (ext=="JPEG") {
            all += QString("*.%1 *.jpg").arg(QString(*it).lower());
        } else {
            all += QString("*.%1").arg(QString(*it).lower());
        } */
    }
    filters.append(QObject::tr("All Image Files (%1)").arg(all));
    filters.append(QObject::tr("All Files (*.*)"));

    fileDlg.setFilters(filters);
    fileDlg.setMode(Q3FileDialog::ExistingFile);
    fileDlg.setCaption(QObject::tr("Open Image"));
    fileDlg.setDir(defDir);
    fileDlg.setSelectedFilter(defFilter);

    if (fileDlg.exec()==QDialog::Accepted) {
        fn = fileDlg.selectedFile();
        cancel = false;
    } else {
        cancel = true;
    }

    // store new default settings:
    if (!cancel) {
        PF_SETTINGS->beginGroup("/Paths");
        PF_SETTINGS->writeEntry("/OpenImage", QFileInfo(fn).dirPath(true));
        PF_SETTINGS->writeEntry("/ImageFilter", fileDlg.selectedFilter());
        PF_SETTINGS->endGroup();
    }

    return fn;
}



void WF_DialogFactory::requestOptions(PF_ActionInterface* action,
                                      bool on, bool update) {
	PF_DEBUG->print("QG_DialogFactory::requestOptions");

    if (action==NULL) {
        PF_DEBUG->print(PF_Debug::D_WARNING,
        	"QG_DialogFactory::requestOptions: action is NULL");
        return;
    }

    switch (action->rtti()) {
    case LX_Define::ActionPrintPreview:
        requestPrintPreviewOptions(action, on, update);
        break;

    case LX_Define::ActionDrawLine:
		PF_DEBUG->print("QG_DialogFactory::requestOptions: line");
        requestLineOptions(action, on);
		PF_DEBUG->print("QG_DialogFactory::requestOptions: line: OK");
        break;
		
    case LX_Define::ActionDrawPolyline:
        requestPolylineOptions(action, on, update);
        break;

    case LX_Define::ActionDrawLineAngle:
        requestLineAngleOptions(action, on, update);
        break;

    case LX_Define::ActionDrawLineParallel:
        requestLineParallelOptions(action, on, update);
        break;

    case LX_Define::ActionDrawLineParallelThrough:
        requestLineParallelThroughOptions(action, on, update);
        break;

    case LX_Define::ActionDrawLineBisector:
        requestLineBisectorOptions(action, on, update);
        break;

    case LX_Define::ActionDrawLineRelAngle:
        requestLineRelAngleOptions(action, on, update);
        break;

    case LX_Define::ActionDrawLinePolygon:
        requestLinePolygonOptions(action, on, update);
        break;

    case LX_Define::ActionDrawLinePolygon2:
        requestLinePolygon2Options(action, on, update);
        break;

    case LX_Define::ActionDrawArc:
        requestArcOptions(action, on, update);
        break;
    
	case LX_Define::ActionDrawArcTangential:
        requestArcTangentialOptions(action, on, update);
        break;

    case LX_Define::ActionDrawCircleCR:
        requestCircleOptions(action, on, update);
        break;
		
    case LX_Define::ActionDrawSpline:
        requestSplineOptions(action, on, update);
        break;

    case LX_Define::ActionDrawText:
        requestTextOptions(action, on, update);
        break;

    case LX_Define::ActionBlocksInsert:
        requestInsertOptions(action, on, update);
        break;

    case LX_Define::ActionDrawImage:
        requestImageOptions(action, on, update);
        break;

    case LX_Define::ActionDimAligned:
        requestDimensionOptions(action, on, update);
        break;

    case LX_Define::ActionDimLinear:
        requestDimensionOptions(action, on, update);
        if (((WF_DimLinear*)action)->hasFixedAngle()==false) {
            requestDimLinearOptions(action, on, update);
        }
        break;

    case LX_Define::ActionDimRadial:
        requestDimensionOptions(action, on, update);
        break;

    case LX_Define::ActionDimDiametric:
        requestDimensionOptions(action, on, update);
        break;

    case LX_Define::ActionDimAngular:
        requestDimensionOptions(action, on, update);
        break;

    case LX_Define::ActionModifyTrimAmount:
        requestTrimAmountOptions(action, on, update);
        break;

    case LX_Define::ActionModifyMoveRotate:
        requestMoveRotateOptions(action, on, update);
        break;

    case LX_Define::ActionModifyBevel:
        requestBevelOptions(action, on, update);
        break;

    case LX_Define::ActionModifyRound:
        requestRoundOptions(action, on, update);
        break;

    case LX_Define::ActionLibraryInsert:
        requestLibraryInsertOptions(action, on, update);
        break;

    default:
        break;
    }
	PF_DEBUG->print("QG_DialogFactory::requestOptions: OK");
}



/**
 * Shows a widget for options for the action: "print preview"
 */
void WF_DialogFactory::requestPrintPreviewOptions(PF_ActionInterface* action,
        bool on, bool update) {

    static UI_PrintPreviewOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_PrintPreviewOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}


/**
 * Shows a widget for options for the action: "draw line"
 */
void WF_DialogFactory::requestLineOptions(PF_ActionInterface* action,
        bool on) {
    static UI_LineOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_LineOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action);
            toolWidget->show();
        }
    }
	PF_DEBUG->print("QG_DialogFactory::requestLineOptions: OK");
}


/**
 * Shows a widget for options for the action: "draw polyline"
 */
void WF_DialogFactory::requestPolylineOptions(PF_ActionInterface* action,
        bool on, bool update) {
		
    static UI_PolylineOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_PolylineOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
            toolWidget->show();
        }
    }
}



/**
 * Shows a widget for options for the action: "draw line parallel"
 */
void WF_DialogFactory::requestLineParallelOptions(PF_ActionInterface* action,
        bool on, bool update) {
    static UI_LineParallelOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
           toolWidget = new UI_LineParallelOptions();
           optionWidget->addWidget(toolWidget);
           toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for options for the action: "draw line parallel through"
 */
void WF_DialogFactory::requestLineParallelThroughOptions(
    PF_ActionInterface* action,
    bool on, bool update) {
    static UI_LineParallelThroughOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_LineParallelThroughOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}


/**
 * Shows a widget for options for the action: "line angle"
 */
void WF_DialogFactory::requestLineAngleOptions(PF_ActionInterface* action,
        bool on, bool update) {

    static UI_LineAngleOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_LineAngleOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
            //toolWidget->setData(&angle, &length, fixedAngle, update);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for options for the action: "line relative angle"
 */
void WF_DialogFactory::requestLineRelAngleOptions(PF_ActionInterface* action,
        bool on, bool update) {

    static UI_LineRelAngleOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_LineRelAngleOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
            //toolWidget->setData(&angle, &length, fixedAngle, update);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for options for the action: "line angle"
 */
void WF_DialogFactory::requestLineBisectorOptions(PF_ActionInterface* action,
        bool on, bool update) {

    static UI_LineBisectorOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_LineBisectorOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for options for the action: "draw polygon"
 */
void WF_DialogFactory::requestLinePolygonOptions(PF_ActionInterface* action,
        bool on, bool update) {
    static UI_LinePolygonOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_LinePolygonOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for options for the action: "draw polygon2"
 */
void WF_DialogFactory::requestLinePolygon2Options(PF_ActionInterface* action,
        bool on, bool update) {
    static UI_LinePolygon2Options* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_LinePolygon2Options();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for arc options.
 */
void WF_DialogFactory::requestArcOptions(PF_ActionInterface* action,
        bool on, bool update) {

    static UI_ArcOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_ArcOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
            //toolWidget->setData(&data);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for tangential arc options.
 */
void WF_DialogFactory::requestArcTangentialOptions(PF_ActionInterface* action,
        bool on, bool update) {

    static UI_ArcTangentialOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_ArcTangentialOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
            //toolWidget->setData(&data);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for arc options.
 */
void WF_DialogFactory::requestCircleOptions(PF_ActionInterface* action,
        bool on, bool update) {
    static UI_CircleOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_CircleOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}


/**
 * Shows a widget for spline options.
 */
void WF_DialogFactory::requestSplineOptions(PF_ActionInterface* action,
        bool on, bool update) {
    static UI_SplineOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_SplineOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for text options.
 */
void WF_DialogFactory::requestTextOptions(PF_ActionInterface* action,
        bool on, bool update) {

    static UI_TextOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_TextOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}


/**
 * Shows a widget for insert options.
 */
void WF_DialogFactory::requestInsertOptions(PF_ActionInterface* action,
        bool on, bool update) {

    static UI_InsertOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_InsertOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for image options.
 */
void WF_DialogFactory::requestImageOptions(PF_ActionInterface* action,
        bool on, bool update) {

    static UI_ImageOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_ImageOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for dimension options.
 */
void WF_DialogFactory::requestDimensionOptions(PF_ActionInterface* action,
        bool on, bool update) {
    //static QLabel* l = NULL;
    static UI_DimOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_DimOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for linear dimension options.
 */
void WF_DialogFactory::requestDimLinearOptions(PF_ActionInterface* action,
        bool on, bool update) {
    //static QLabel* l = NULL;
    static UI_DimLinearOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_DimLinearOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for 'snap to a point with a given distance' options.
 */
void WF_DialogFactory::requestSnapDistOptions(double& dist, bool on) {
    static UI_SnapDistOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_SnapDistOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setDist(&dist);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for 'snap to a point with a given distance' options.
 */
void WF_DialogFactory::requestMoveRotateOptions(PF_ActionInterface* action,
        bool on, bool update) {
    static UI_MoveRotateOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_MoveRotateOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for 'trim amount' options.
 */
void WF_DialogFactory::requestTrimAmountOptions(PF_ActionInterface* action,
        bool on, bool update) {
    static UI_TrimAmountOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_TrimAmountOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}



/**
 * Shows a widget for beveling options.
 */
void WF_DialogFactory::requestBevelOptions(PF_ActionInterface* action,
        bool on, bool update) {
    static UI_BevelOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_BevelOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
            toolWidget->show();
        }
    }
}



/**
 * Shows a widget for rounding options.
 */
void WF_DialogFactory::requestRoundOptions(PF_ActionInterface* action,
        bool on, bool update) {
    static UI_RoundOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_RoundOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
            toolWidget->show();
        }
    }
}



/**
 * Shows a widget for library insert options.
 */
void WF_DialogFactory::requestLibraryInsertOptions(PF_ActionInterface* action,
        bool on, bool update) {
    static UI_LibraryInsertOptions* toolWidget = NULL;

    if (optionWidget!=NULL) {
        if (toolWidget!=NULL) {
            delete toolWidget;
            toolWidget = NULL;
        }
        if (on==true) {
            toolWidget = new UI_LibraryInsertOptions();
            optionWidget->addWidget(toolWidget);
            toolWidget->setAction(action, update);
			toolWidget->show();
        }
    }
}



/**
 * Shows the given toolbar.
 */
void WF_DialogFactory::requestToolBar(LX_Define::ToolBarId id) {
    if (cadToolBar!=NULL) {
        cadToolBar->showToolBar(id);
    }
}



/**
 * Shows the select toolbar with the given action to launch.
 */
void WF_DialogFactory::requestToolBarSelect(PF_ActionInterface* selectAction,
        LX_Define::ActionType nextAction) {
    if (cadToolBar!=NULL) {
        cadToolBar->showToolBarSelect(selectAction, nextAction);
    }
}



/**
 * Shows attributes options dialog presenting the given data.
 */
bool WF_DialogFactory::requestAttributesDialog(PF_AttributesData& data,
        PF_LayerList& layerList) {

    UI_DlgAttributes dlg(parent);
    dlg.setData(&data, layerList);
    if (dlg.exec()) {
        dlg.updateData();
        return true;
    }
    return false;
}



/**
 * Shows move options dialog presenting the given data.
 */
bool WF_DialogFactory::requestMoveDialog(PF_MoveAttribute& data) {
    UI_DlgMove dlg(parent);
    dlg.setData(&data);
    if (dlg.exec()) {
        dlg.updateData();
        return true;
    }
    return false;
}



/**
 * Shows rotate options dialog presenting the given data.
 */
bool WF_DialogFactory::requestRotateDialog(PF_RotateAttribute& data) {
    UI_DlgRotate dlg(parent);
    dlg.setData(&data);
    if (dlg.exec()) {
        dlg.updateData();
        return true;
    }
    return false;
}



/**
 * Shows scale options dialog presenting the given data.
 */
bool WF_DialogFactory::requestScaleDialog(PF_ScaleAttribute& data) {
    UI_DlgScale dlg(parent);
    dlg.setData(&data);
    if (dlg.exec()) {
        dlg.updateData();
        return true;
    }
    return false;
}



/**
 * Shows mirror options dialog presenting the given data.
 */
bool WF_DialogFactory::requestMirrorDialog(PF_MirrorAttribute& data) {
    UI_DlgMirror dlg(parent);
    dlg.setData(&data);
    if (dlg.exec()) {
        dlg.updateData();
        return true;
    }
    return false;
}



/**
 * Shows move/rotate options dialog presenting the given data.
 */
bool WF_DialogFactory::requestMoveRotateDialog(PF_MoveRotateAttribute& data) {
    UI_DlgMoveRotate dlg(parent);
    dlg.setData(&data);
    if (dlg.exec()) {
        dlg.updateData();
        return true;
    }
    return false;
}



/**
 * Shows rotate around two centers options dialog presenting the given data.
 */
bool WF_DialogFactory::requestRotate2Dialog(PF_Rotate2Attribute& data) {
    UI_DlgRotate2 dlg(parent);
    dlg.setData(&data);
    if (dlg.exec()) {
        dlg.updateData();
        return true;
    }
    return false;
}



/**
 * Shows a dialog to edit the given entity.
 */
bool WF_DialogFactory::requestModifyEntityDialog(PF_Entity* entity) {
    if (entity==NULL) {
        return false;
    }

    bool ret = false;

    switch (entity->rtti()) {
    case LX_Define::EntityPoint: {
            UI_DlgPoint dlg(parent);
            dlg.setPoint(*((PF_Point*)entity));
            if (dlg.exec()) {
                dlg.updatePoint();
                ret = true;
            }
        }
        break;

    case LX_Define::EntityLine: {
            UI_DlgLine dlg(parent);
            dlg.setLine(*((PF_Line*)entity));
            if (dlg.exec()) {
                dlg.updateLine();
                ret = true;
            }
        }
        break;

    case LX_Define::EntityArc: {
            UI_DlgArc dlg(parent);
            dlg.setArc(*((PF_Arc*)entity));
            if (dlg.exec()) {
                dlg.updateArc();
                ret = true;
            }
        }
        break;

    case LX_Define::EntityCircle: {
            UI_DlgCircle dlg(parent);
            dlg.setCircle(*((PF_Circle*)entity));
            if (dlg.exec()) {
                dlg.updateCircle();
                ret = true;
            }
        }
        break;

    case LX_Define::EntityEllipse: {
            UI_DlgEllipse dlg(parent);
            dlg.setEllipse(*((PF_Ellipse*)entity));
            if (dlg.exec()) {
                dlg.updateEllipse();
                ret = true;
            }
        }
        break;
		
    case LX_Define::EntitySpline: {
            UI_DlgSpline dlg(parent);
            dlg.setSpline(*((PF_Spline*)entity));
            if (dlg.exec()) {
                dlg.updateSpline();
                ret = true;
            }
        }
        break;

    case LX_Define::EntityInsert: {
            UI_DlgInsert dlg(parent);
            dlg.setInsert(*((PF_Insert*)entity));
            if (dlg.exec()) {
                dlg.updateInsert();
                ret = true;
                entity->update();
            }
        }
        break;

    case LX_Define::EntityDimAligned:
    case LX_Define::EntityDimAngular:
    case LX_Define::EntityDimDiametric:
    case LX_Define::EntityDimRadial: {
            UI_DlgDimension dlg(parent);
            dlg.setDim(*((PF_Dimension*)entity));
            if (dlg.exec()) {
                dlg.updateDim();
                ret = true;
                ((PF_Dimension*)entity)->update(true);
            }
        }
        break;
		
    case LX_Define::EntityDimLinear: {
            UI_DlgDimLinear dlg(parent);
            dlg.setDim(*((PF_DimLinear*)entity));
            if (dlg.exec()) {
                dlg.updateDim();
                ret = true;
                ((PF_DimLinear*)entity)->update(true);
            }
        }
        break;
		
    case LX_Define::EntityText: {
            UI_DlgText dlg(parent);
            dlg.setText(*((PF_Text*)entity), false);
            if (dlg.exec()) {
                dlg.updateText();
                ret = true;
                ((PF_Text*)entity)->update();
            }
        }
        break;

    case LX_Define::EntityHatch: {
            UI_DlgHatch dlg(parent);
            dlg.setHatch(*((PF_Hatch*)entity), false);
            if (dlg.exec()) {
                dlg.updateHatch();
                ret = true;
                ((PF_Hatch*)entity)->update();
            }
        }
        break;

    default:
        break;
    }

    return ret;
}



/**
 * Shows a dialog to edit the attributes of the given dimension entity.
 */
 /*
bool QG_DialogFactory::requestDimAlignedDialog(PF_DimAligned* dim) {
    if (dim==NULL) {
        return false;
    }

    QG_DlgDimAligned dlg(parent);
    dlg.setDim(*dim, true);
    if (dlg.exec()) {
        dlg.updateDim();
        return true;
    }

    return false;
}
*/



/**
 * Shows a dialog to edit the attributes of the given text entity.
 */
bool WF_DialogFactory::requestTextDialog(PF_Text* text) {
    if (text==NULL) {
        return false;
    }

    UI_DlgText dlg(parent);
    dlg.setText(*text, true);
    if (dlg.exec()) {
        dlg.updateText();
        return true;
    }

    return false;
}


/**
 * Shows a dialog to edit pattern / hatch attributes of the given entity.
 */
bool WF_DialogFactory::requestHatchDialog(PF_Hatch* hatch) {
    if (hatch==NULL) {
        return false;
    }

    PF_PATTERNLIST->init();

    UI_DlgHatch dlg(parent);
    dlg.setHatch(*hatch, true);
    if (dlg.exec()) {
        dlg.updateHatch();
        return true;
    }

    return false;
}


/**
 * Shows dialog for general application options.
 */
void WF_DialogFactory::requestOptionsGeneralDialog() {
    UI_DlgOptionsGeneral dlg(parent);
    dlg.exec();
}



/**
 * Shows dialog for drawing options.
 */
void WF_DialogFactory::requestOptionsDrawingDialog(PF_Graphic& graphic) {
    UI_DlgOptionsDrawing dlg(parent);
    dlg.setGraphic(&graphic);
    dlg.exec();
}


/**
 * Back to last menu in cad toolbar.
 */
void WF_DialogFactory::requestPreviousMenu() {
    if (cadToolBar!=NULL) {
        cadToolBar->showToolBarMain();
    }
}



/**
 * Called whenever the mouse position changed.
 */
void WF_DialogFactory::updateCoordinateWidget(const PF_Vector& abs,
        const PF_Vector& rel, bool updateFormat) {
    if (coordinateWidget!=NULL) {
        coordinateWidget->setCoordinates(abs, rel, updateFormat);
    }
}



/**
 * Called when an action has a mouse hint.
 */
void WF_DialogFactory::updateMouseWidget(const PF_String& left,
        const PF_String& right) {
    if (mouseWidget!=NULL) {
        mouseWidget->setHelp(left, right);
    }
    if (commandWidget!=NULL) {
        commandWidget->setCommand(left);
    }
}



/**
 * Called whenever the selection changed.
 */
void WF_DialogFactory::updateSelectionWidget(int num) {
    if (selectionWidget!=NULL) {
        selectionWidget->setNumber(num);
    }
}


/**
 * Called when an action needs to communicate 'message' to the user.
 */
void WF_DialogFactory::commandMessage(const PF_String& message) {
	PF_DEBUG->print("QG_DialogFactory::commandMessage");
    if (commandWidget!=NULL) {
        commandWidget->appendHistory(message);
    }
	PF_DEBUG->print("QG_DialogFactory::commandMessage: OK");
}



/**
 * Converts an extension to a format description.
 * e.g. "PNG" to "Portable Network Graphic"
 *
 * @param Extension
 * @return Format description
 */
QString WF_DialogFactory::extToFormat(const QString& ext) {
    QString e = ext.lower();

    if (e=="bmp") {
        return QObject::tr("Windows Bitmap");
    } else if (e=="jpeg" || e=="jpg") {
        return QObject::tr("Joint Photographic Experts Group");
    } else if (e=="gif") {
        return QObject::tr("Graphics Interchange Format");
    } else if (e=="mng") {
        return QObject::tr("Multiple-image Network Graphics");
    } else if (e=="pbm") {
        return QObject::tr("Portable Bit Map");
    } else if (e=="pgm") {
        return QObject::tr("Portable Grey Map");
    } else if (e=="png") {
        return QObject::tr("Portable Network Graphic");
    } else if (e=="ppm") {
        return QObject::tr("Portable Pixel Map");
    } else if (e=="xbm") {
        return QObject::tr("X Bitmap Format");
    } else if (e=="xpm") {
        return QObject::tr("X Pixel Map");
    }
    else {
        return ext.upper();
    }
}


